<?php
declare (strict_types = 1);

namespace app\controller\backend;

use app\exception\ModelEmptyException;
use app\exception\ModelException;
use app\model\InnerChart;
use app\model\RecycleBin;
use app\model\SubContent;
use app\model\SubContentCheck;
use app\model\SubContentCheckStep;
use app\model\SysSetting;
use app\service\CacheService;
use app\service\CiZhuaService;
use app\service\ContentService;
use app\service\ModuleFieldService;
use app\service\TranslateService;
use app\validate\ContentValidate;
use think\db\exception\DbException;
use think\Exception;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Lang;
use Vtiful\Kernel\Excel;
use function Complex\csc;

class ContentController extends BaseController
{

    // 文章批量上传
    public function articleUpload(ContentService $contentService): \think\response\Json
    {
        if($this->request->isPost()){
            $param = $this->request->param();
            $file = $this->request->file('file');
            $param['file'] = $file;
            if(is_string($param['category_id'])){
                $param['category_id'] = explode(',', $param['category_id']);
            }
            try{
                validate(ContentValidate::class)->scene('articleUpload')->check($param);
            }catch (ValidateException $e){
                return jsonReturn(-1,$e->getError());
            }
            $param['admin'] = $this->admin;
            $res = $contentService->articleUpload($param);
            CacheService::clear();
            return  json($res);
        }
         return jsonReturn(-1,Lang::get('请求方式错误'));
    }

    // 提取文章简介
    public function descExtraction(ContentService $contentService): \think\response\Json
    {
        $content = input('content');
        $res = $contentService -> descExtraction($content);
        return jsonReturn(0,lang('成功'),$res);
    }

    // 图片本地化
    public function imgLocal(ContentService $contentService): \think\response\Json
    {
        $content = input('content');
        $website = input('website');
        $res = $contentService -> imgExtraction($content,$this->admin['seller_id'],$website);
        return jsonReturn(0,lang('成功'),$res);
    }

    public function wordSearch(CiZhuaService $ciZhuaService)
    {
        $content = input('content');
        $sysSetting = new SysSetting();
        $key = $sysSetting->getSysSettingValue([['title','=','cizhua_secret']])['data'];

        if (empty($key)) {
            return jsonReturn(-1,lang('没有配置密钥，请去系统设置-第三方设置中填写词爪密钥'));
        }

        $res = $ciZhuaService->wordSearch($key, $content);
        $res = json_decode($res, true);
        if ($res['code'] != 0) {
            return json($res);
        }
        return jsonReturn(0,lang('成功'), $res['data']);
    }

    /**
     * 内容添加内链
     * @throws DbException
     */
    public function addInnerChat(ContentService $contentService): \think\response\Json
    {
        $param = input('post.');
        try{
            validate(ContentValidate::class)->scene('addInnerChat')->check($param);
        }catch (ValidateException $e){
            return jsonReturn(422, $e->getError());
        }
        $sellerId= $this->admin['seller_id'];
        $InnerChart = new InnerChart();
        $innerChart = $InnerChart->getAllInnerChart(['seller_id'=>$sellerId,'website_id'=>$param['website_id'],'status'=>1],'weight desc','id,weight,keyword,url,new_page_open')['data'];
        if(empty($innerChart)){
            return jsonReturn(0,lang('成功'),$param['content']);
        }
        $subId = (int)input('sub_id');
        if($subId){
            $SubContent =  new SubContent();
            $subContent = $SubContent -> getSubContent(['id'=>$subId,'seller_id'=>$this->admin['seller_id'],'is_del'=>1])['data'];
        }else{
            $subContent = null;
        }
        $content = $contentService->autoLinks($param['content'],$innerChart,$subContent);
        CacheService::clear();
        return jsonReturn(0,lang('成功'),$content);
    }

    /**
     * 文章列表
     *
     * @return \think\Response
     */
    public function index(ContentService $contentService): \think\Response
    {
        $status = input('param.status');
        $categoryIds = input('param.category_id');
        $title = input('param.title');

        $limit = $this->setLimit();
        $param = [
            'seller_id' => $this->admin['seller_id'],
            'category_ids' => $categoryIds,
            'limit' => $limit,
            'lang' => input('param.lang'),
            'website_id' => (int)input('param.website_id'),
            'title' => $title,
            'is_del' => 1,
        ];

        $where = [];
        switch ($status) {
            case 1://已发布
                $where[] = ['status', '=', 1];
                $where[] = ['publish_time', '<=', date('Y-m-d H:i:s')];
                $where[] = ['check_status', '=', 3];
                break;
            case 2://待发布
                $where[] = ['status', '=', 1];
                $where[] = ['publish_time', '>', date('Y-m-d H:i:s')];
                $where[] = ['check_status', '=', 3];
                break;
            case 3://待审核
                $where[] = ['status', '=', 1];
                $where[] = ['check_status', 'in', [1,2]];
                break;
            case 4://被驳回
                $where[] = ['status', '=', 1];
                $where[] = ['check_status', '=', 4];
                break;
            case 5://已下线
                $where[] = ['status', '=', 2];
                break;
            case 6://草稿
                $where[] = ['status', '=', 3];
                break;
        }
        $param['where'] = $where;

        try {
            $res = $contentService->indexContent($param);
        } catch (ModelEmptyException | ModelException | DbException $e) {
            return jsonReturn(50013,$e->getMessage());
        }
        return $res;
    }

    /**
     * 待审核列表
     * @return \think\response\Json
     */
    public function checkList(ContentService $contentService)
    {
        $categoryIds = input('param.category_id');
        $title = input('param.title');
        $type = $this->request->param('type', 1);

        $contentCheckModel = new SubContentCheck();
        if ($type == 1) {
            // 获取需要自己审核的待审核内容id
            $ids = $contentCheckModel->where([
                'check_user_id' => $this->admin['uid'],
                'status' => 2,
            ])->column('real_id');
            $contentWhere[] = ['id', 'in', $ids];
            $contentWhere[] = ['check_status', 'in', [1,2]];
        } else {
            // 获取自己提交的需要审核的内容id
            $contentWhere[] = ['admin_id', '=', $this->admin['uid']];
        }
        $contentWhere[] = ['status', 'in', [1,2]];

        $limit = $this->setLimit();
        $param = [
            'seller_id' => $this->admin['seller_id'],
            'category_ids' => $categoryIds,
            'limit' => $limit,
            'lang' => input('param.lang'),
            'website_id' => (int)input('param.website_id'),
            'title' => $title,
            'is_del' => 1,
            'where' => $contentWhere
        ];
        try {
            $res = $contentService->indexContent($param);
        } catch (ModelEmptyException | ModelException | DbException $e) {
            return jsonReturn(50013,$e->getMessage());
        }
        return $res;
    }

    /**
     * 回收站列表
     * @return \think\response\Json
     */
    public function recycleBinList(ContentService $contentService)
    {
        $categoryIds = input('param.category_id');
        $title = input('param.title');

        $limit = $this->setLimit();
        $param = [
            'seller_id' => $this->admin['seller_id'],
            'category_ids' => $categoryIds,
            'limit' => $limit,
            'lang' => input('param.lang'),
            'website_id' => (int)input('param.website_id'),
            'title' => $title,
            'is_del' => 2,
        ];
        try {
            $res = $contentService->indexContent($param);
        } catch (ModelEmptyException | ModelException | DbException $e) {
            return jsonReturn(50013,$e->getMessage());
        }
        return $res;
    }

    /**
     * 批量审核
     * @return \think\response\Json
     */
    public function checkAll()
    {
        $param = $this->request->only([
            'check_data' => [],
            'status' => 3,
            'reason' => '',
            'files' => '',
        ]);

        // 内容多版本审核

        if (empty($param['check_data']) || !in_array($param['status'], [3,4])) {
            return jsonReturn(-1, lang('参数错误'));
        }
        if (!is_array($param['check_data'])) {
            return jsonReturn(-1, lang('参数错误'));
        }

        if (is_array($param['files'])) {
            $param['files'] = implode(',', $param['files']);
        }

        Db::startTrans();
        try {
            $contentService = new ContentService();
            foreach ($param['check_data'] as $check) {
                $newParam = $param;
                unset($newParam['check_data']);
                $newParam['real_id'] = $check['id'];
                $newParam['version'] = $check['version'];
                $newParam['admin'] = $this->admin;

                $res = $contentService->check($newParam);
                if ($res['code'] != 0) {
                    throw new Exception($check['id'] . lang('审核失败！版本：')."{$check['version']}！" . $res['code'] . $res['msg']);
                }
            }
        } catch (\Exception $e) {
            Db::rollback();
            return jsonReturn(-3, $e->getMessage(), $e->getTrace());
        }
        Db::commit();
        return jsonReturn(0, lang('操作成功'));
    }

    public function editStatus(ContentService $contentService)
    {
        $param = $this->request->only([
            'id' => [],
            'status' => 1,
        ]);
        $param['seller_id'] = $this->admin['seller_id'];

        return json($contentService->editStatus($param));
    }

    /*
     * 批量删除
     */
    public function delAll(ContentService $contentService)
    {
        $param = $this->request->only(['ids']);

        if (!is_array($param['ids'])) {
            $param['ids'] = explode(',', $param['ids']);
        }
        $subContentModel = new SubContent();
        $list = $subContentModel->where('id', 'in', $param['ids'])->column('id, module_id');

        foreach ($list as $v) {
            $v['seller_id'] = $this->admin['seller_id'];
            $v['admin_id'] = $this->admin['uid'];
            $v['name'] = $this->admin['name'];

            $res = $contentService->deleteContent($v);
            CacheService::clear();
        }

        return $res;
    }

    // 批量恢复
    public function recoverAll(ModuleFieldService $fieldService)
    {
        $param = $this->request->only(['ids']);
        if (!is_array($param['ids'])) {
            $param['ids'] = explode(',', $param['ids']);
        }

        $subContentModel = new SubContent();
        $list = $subContentModel->where('id', 'in', $param['ids'])->column('id, module_id');

        $ids = array_column($list, 'id');
        $module_ids = array_column($list, 'module_id');
        $recycleBin = new RecycleBin();
        $idArr = $recycleBin->where([
            ['sub_id', 'in', $ids],
            ['module_id', 'in', $module_ids]
        ])->column('id');

        foreach ($idArr as $id) {
            $res = $fieldService->resotreData($id,$this->admin['seller_id']);
        }
        CacheService::clear();

        return $res;
    }

    /**
     * 获取栏目字段
     *
     */
    public function create(ContentService $contentService): \think\response\Json
    {
        $categoryId = (int)input('category_id');
        if(!$categoryId){
            return jsonReturn(-1,lang('栏目ID不能为空'));
        }
        $param = [
            'seller_id' => $this->admin['seller_id'],
            'category_id' => $categoryId
        ];
        try {
            $res = $contentService->createContent($param);
        } catch (ModelEmptyException | ModelException $e) {
            return jsonReturn(-3,$e->getMessage());
        }
        return $res;
    }

    /**
     * 栏目内容新增
     *
     * @return \think\Response
     */
    public function save(ContentService $contentService): \think\Response
    {
        if(!request()->isPost()){
            return jsonReturn(-2,lang('请求方法错误'));
        }
        $param = input('post.');
        try{
            validate(ContentValidate::class)->scene('save')->check($param);
        }catch (ValidateException $e){
            return jsonReturn(422, $e->getError());
        }
        $param['admin'] = $this->admin;
        unset($param['main_content']['id']);//添加接口以防冲突不需要id
        unset($param['sub_content']['id']);//添加接口以防冲突不需要id
        if(empty($param['sub_content']['publish_time'])){
            $param['sub_content']['publish_time'] = date('Y-m-d H:i:s',time());
        }
        if(!isset($param['main_content'])){
            $param['main_content'] = [];
        }
        try {
            $res =  $contentService->saveContent($param);
        } catch (ModelEmptyException | ModelException $e) {
            return jsonReturn(-3,$e->getMessage());
        }
        CacheService::clear();
        return json($res);

    }

    /**
     * 显示指定的资源
     *
     */
    public function read(ContentService $contentService): \think\response\Json
    {
        $param = request()->only(['id','module_id','website_id','lang']);
        try {
            validate(ContentValidate::class)->scene('read')->check($param);
        }catch(ValidateException $e){
            return jsonReturn(-422,$e->getError());
        }
        $param['seller_id'] = $this->admin['seller_id'];
        try {
            $res = $contentService->readContent($param);
        } catch (ModelEmptyException | ModelException $e) {
            return jsonReturn(50025,$e->getMessage());
        }
        return $res;

    }

    /**
     * 保存更新的资源
     *
     * @return \think\Response
     */
    public function update(ContentService $contentService): \think\Response
    {
        if(!request()->isPost()){
            return jsonReturn(-2,lang('请求方法错误'));
        }

        $param = input('post.');
        try{
            validate(ContentValidate::class)->scene('update')->check($param);
        }catch (ValidateException $e){
            return jsonReturn(422, $e->getError());
        }

        $param['admin'] = $this->admin;
        if(empty($param['sub_content']['publish_time'])){
            $param['sub_content']['publish_time'] = date('Y-m-d H:i:s',time());
        }
        try {
            $res =  $contentService->updateContent($param);
        } catch (ModelEmptyException | ModelException $e) {
            return jsonReturn(-3,$e->getMessage());
        }
        CacheService::clear();
        return $res;
    }

    /**
     * 删除指定资源
     *
     */
    public function delete(ContentService $contentService): \think\response\Json
    {
        $param = request()->only(['id','module_id']);
        try {
            validate(ContentValidate::class)->scene('delete')->check($param);
        }catch(ValidateException $e){
            return jsonReturn(-422,$e->getMessage());
        }
        $param['seller_id'] = $this->admin['seller_id'];
        $param['admin_id'] = $this->admin['uid'];
        $param['name'] = $this->admin['name'];
        CacheService::clear();
        return $contentService->deleteContent($param);

    }

    public function mainContent(ContentService $contentService): \think\response\Json
    {
        if(!request()->isGet()){
            return jsonReturn(-1,lang('请求方法错误'));
        }
        $param = request()->param(['module_id','website_id','page','limit']);
        try {
            validate(ContentValidate::class)->scene('mainContent')->check($param);
        }catch(ValidateException $e){
            return jsonReturn(-422,$e->getMessage());
        }
        $limit = (int)input('param.limit') ?: 10;
        $param = [
            'seller_id' => $this->admin['seller_id'],
            'website_id' => $param['website_id'],
            'module_id' => $param['module_id'],
            'limit' => $limit,
        ];
        try {
            $res = $contentService->mainContent($param);
        } catch (ModelEmptyException | ModelException | DbException $e) {
            return jsonReturn(50013,$e->getMessage());
        }
        return $res;
    }

    /**
     * 修改置顶
     * @throws ModelException
     */
    public function topOpt(ContentService $contentService): \think\response\Json
    {
        if(request()->isPost()){
            $param = input('post.');
            try {
                validate(ContentValidate::class)->scene('topOpt')->check($param);
            }catch(ValidateException $e){
                return jsonReturn(-422,$e->getMessage());
            }
            $param['seller_id'] = $this->admin['seller_id'];
            return $contentService->topOpt($param);
        }
        return jsonReturn(-1,lang('请求方法错误'));
    }

    /**
     *  推荐和修改状态
     * @throws ModelException
     */
    public function recommendAndStatus(ContentService $contentService): \think\response\Json
    {
        if(request()->isPost()){
            $param = input('post.');
            try {
                validate(ContentValidate::class)->scene('recommendAndStatus')->check($param);
            }catch(ValidateException $e){
                return jsonReturn(-422,$e->getMessage());
            }
            $param['seller_id'] = $this->admin['seller_id'];
            CacheService::clear();
            return $contentService->recommendAndStatus($param);
        }
        return jsonReturn(-1,lang('请求方法错误'));
    }

    public function moduleContent(ContentService $contentService): \think\response\Json
    {
        // 关联内容
        $table = input('param.table');
//        $field = input('param.field');
        if(empty($table)){
            return jsonReturn(-1,lang('表名不能为空'));
        }
//        if(empty($field)){
//            return jsonReturn(-2,'关联字段不能为空');
//        }

        $res = $contentService -> getModuleContent($table,$this->admin['seller_id']);
        return jsonReturn($res);
    }

    /**
     * excel导入内容
     */
    public function importExcel()
    {
        $lang = $this->request->param('lang/s',"zh");
        if(empty($_FILES['file'])){
            return jsonReturn(-1,lang("请传入文件"));
        }
        $fileName = $_FILES['file'];
        $temp_file = sys_get_temp_dir();
        $config = ['path' => $temp_file];
        $excel = new Excel($config);
        $tmpName = strrchr($fileName['tmp_name'], '/');
        //读取文件
        $sheetList = $excel->openFile($tmpName)->sheetList();

        if (empty($sheetList)) {
            return jsonReturn(-1, lang('上传文件为空'));
        }
        $sheetData = $excel
            ->openSheet($sheetList[0], Excel::SKIP_EMPTY_ROW)->getSheetData();
        if (!isset($sheetData[1]) || !isset($sheetData[2])) {
            return jsonReturn(-1, lang('上传文件为空'));
        }

        $fieldLocation = array();
        foreach ($sheetData[0] as $key => $value) {
            $fieldLocation[$value] = $key;
        }
        unset($sheetData[0]);
        $needField = ['标题', '链接', '网站', '类别ID','类别','图片'];
        foreach ($needField as $key => $value) {
            if (!isset($fieldLocation[$value])) {
                return jsonReturn(-1, lang('缺少必要列：') . $value);
            }
        }

        //查询栏目id和内容
        $category = Db::name("category")->where(['seller_id'=>$this->admin['seller_id'],'lang'=>$lang])
            ->column("title","id");
        if(empty($category)){
            return jsonReturn(-5, lang("请先添加栏目"));
        }
        try{
            $insertData= $files = $filesUrl = $uploadFiles = [];
            foreach ($sheetData as $k=>$v){
                if(empty($v[0])){
                    return jsonReturn(-4,lang("标题不能为空"));
                }
                if(!empty($v[5]) && !preg_match('/(http:\/\/)|(https:\/\/)/i', $v[5])){
                    return jsonReturn(-4,lang("图片格式错误"));
                }
                if(empty($category[$v[3]])){
                    return jsonReturn(-4,$v[3].lang('对应的分类不存在')."[{$v[4]}]");
                }
                if (!empty($v[5]) && !in_array(trim($v[5]),$files)){
                    $files[]=trim($v[5]);
                    $uploadFiles[$k]['url'] = trim($v[5]);
                    $uploadFiles[$k]['seller_id'] = $this->admin['seller_id'];
                    $uploadFiles[$k]['name'] = $v[4];
                    $uploadFiles[$k]['type'] = 2;
                    $uploadFiles[$k]['storage'] = 1;
                }

                $insertData[$k]['seller_id'] = $this->admin['seller_id'];
                $insertData[$k]['category_id'] = $v[3];
                $insertData[$k]['module_id'] = 1;
                $insertData[$k]['lang'] = $lang;
                $insertData[$k]['title'] = $v[0];
                $insertData[$k]['thumbnail'] = $v[5];
                $insertData[$k]['admin_id'] = $this->admin['uid'];
                $insertData[$k]['author'] = $v[2];
                $insertData[$k]['check_status'] = 3;
                $insertData[$k]['url'] = $v[1];
                $insertData[$k]['publish_time'] = date("Y-m-d H:i:s");
                $insertData[$k]['create_time'] =time();
            }
        }catch (\Exception $e){
            throw new ModelException($e->getMessage(),-1);
        }

        Db::startTrans();
        try{
            if(!empty($uploadFiles)){
                Db::name("attachment")->insertAll($uploadFiles);
                $filesUrl = Db::name("attachment")->where([['url',"in",$files]])->column("id","url");
            }
            foreach ($insertData as $ki=>$data){
                $data['thumbnail'] = isset($filesUrl[$data['thumbnail']])?$filesUrl[$data['thumbnail']]:0;
                $sub_id =  Db::name("sub_content")->insertGetId($data); //文章的id
                Db::name("category_sub_content")->insert([
                    "seller_id"=>$data['seller_id'],
                    "category_id"=>$data['category_id'],
                    "sub_content_id"=>$sub_id,
                ]);
                $mainId = Db::name("article")->insertGetId([
                    "seller_id"=>$data['seller_id'],
                    "lang"=>$lang,
                    "sub_id"=>$sub_id,
                    "create_time"=>time()
                ]);
                Db::name("sub_content")->where(['id'=>$sub_id])->update(['main_id'=>$mainId]);
            }
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            throw new ModelException($e->getMessage(),-2);
        }
        return jsonReturn(0,lang('导入成功'));
    }

}
